package html;

import java.util.HashMap;
import java.util.Map;

import fj.F;
import fj.Unit;
import fj.data.List;
import fj.data.Option;

public class HTMLElem {

	public Map<String,Option<String>> attrMap = new HashMap<String,Option<String>>();
	public Option<String> innerHTML = Option.some("");
	private String tagName;
	protected F<String,HTMLElem> append = new F<String,HTMLElem>()
	{

		@Override
		public HTMLElem f(String arg0) {
			return append(arg0);
		}
		
	};
	
	private F<HTMLElem,F<HTMLElem,HTMLElem>> foldAppend = new F<HTMLElem,F<HTMLElem,HTMLElem>>()
	{

		@Override
		public F<HTMLElem, HTMLElem> f(final HTMLElem parent) {
			
			return new F<HTMLElem,HTMLElem>(){

				@Override
				public HTMLElem f(HTMLElem elem) {
					
					return parent.append(elem);
				}
				
			};
		}
		
	};

	
	
	public HTMLElem(String tagName)
	{
		this.tagName=tagName;
	}
	public HTMLElem(String tagName, Map<String,Option<String>> attrMap)
	{
		this.tagName=tagName;
		this.attrMap=attrMap;
	}
	public String toString()
	{
		
		StringBuffer sb = new StringBuffer();
		sb.append("<"+tagName);
		sb.append(addAttrs.f(attrMap));
		sb.append(">");
		sb.append(innerHTML.orSome(""));
		sb.append("</"+tagName+">");
		return sb.toString();
	}
	
	public static F<Map<String, Option<String>>, String> addAttrs = new F<Map<String,Option<String>>,String>()
	{

		@Override
		public String f(Map<String, Option<String>> attrs) {
			StringBuffer sb  = new StringBuffer();
			
			for(String key : attrs.keySet())
			{
				sb.append(" "+key+"=\""+attrs.get(key).some()+"\"");
			}
			return sb.toString();
		}
		
	};

	public HTMLElem append(HTMLElem innerHTML) {
		this.innerHTML= Option.some(this.innerHTML.orSome("")+innerHTML.toString());
		return this;
	}
	public HTMLElem append(String content) {
		this.innerHTML=Option.some(content);
		return this;
	}
	public HTMLElem append(List<HTMLElem> childElems) {
		return childElems.foldLeft1(foldAppend);
	}


	public HTMLElem addAttr(String string, String string2) {
		attrMap.put(string, Option.some(string2));
		return this;
	}
	public HTMLElem appendTo(HTMLElem articleElem) {
		articleElem.append(this);
		return this;
	}
	
}
